﻿using Abp.Application.Services.Dto;
using Abp.Domain.Repositories;
using Abp.Linq.Extensions;
using LpbPrj.Client;
using LpbPrj.Client.Reports;
using LpbPrj.Client.Reports.Dtos;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using System.Threading.Tasks;

namespace MyPrj.WPF.ReportInfoes
{
    public class ReportService : ClientAppServiceBase, IReportService
    {
        private readonly IRepository<Report, long> _entityRepository;

        public ReportService(IRepository<Report, long> entityRepository)
        {
            _entityRepository = entityRepository;
        }

        public async Task<PagedResultDto<ReportListDto>> GetPaged(GetReportsPaged input)
        {
            var query = _entityRepository.GetAll().AsNoTracking()
                .WhereIf(input.CreatorUserId.HasValue, p => p.CreatorUserId.HasValue && p.CreatorUserId.Value == input.CreatorUserId.Value)
                .WhereIf(input.PatientId.HasValue, p => p.PatientId == input.PatientId.Value)
                .Where(p => p.RecordId == input.RecordId);

            var count = await query.CountAsync();
            var entityList = await query
                    .OrderByDescending(p => p.CreationTime)
                    .PageBy(input)
                    .ToListAsync();

            var entityListDtos = ObjectMapper.Map<List<ReportListDto>>(entityList);
            return new PagedResultDto<ReportListDto>(count, entityListDtos);
        }

        public async Task<ReportListDto> GetById(EntityDto<long> input)
        {
            var entity = await _entityRepository.GetAll().AsNoTracking().FirstOrDefaultAsync(p => p.Id == input.Id);
            return ObjectMapper.Map<ReportListDto>(entity);
        }

        public async Task<ReportEditDto> GetForEdit(NullableIdDto<long> input)
        {
            ReportEditDto editDto = null;

            if (input.Id.HasValue)
            {
                var entity = await _entityRepository.GetAll().AsNoTracking().FirstOrDefaultAsync(p => p.Id == input.Id.Value);
                editDto = ObjectMapper.Map<ReportEditDto>(entity);
            }
            else
            {
                editDto = new ReportEditDto();
            }

            return editDto;
        }

        public async Task<ReportListDto> CreateOrUpdate(ReportEditDto input)
        {
            long? id = input.Id;

            if (input.Id.HasValue)
            {
                await Update(input);
            }
            else
            {
                id = await Create(input);
            }
            CurrentUnitOfWork.SaveChanges();
            if (id.HasValue)
            {
                var entity = await _entityRepository.GetAll().AsNoTracking().FirstOrDefaultAsync(p => p.Id == id.Value);
                return ObjectMapper.Map<ReportListDto>(entity);
            }

            return null;
        }

        protected virtual async Task<long> Create(ReportEditDto input)
        {
            var entity = ObjectMapper.Map<Report>(input);
            return await _entityRepository.InsertAndGetIdAsync(entity);
        }

        protected virtual async Task Update(ReportEditDto input)
        {
            var entity = await _entityRepository.GetAll().AsNoTracking().FirstOrDefaultAsync(p => p.Id == input.Id.Value);
            ObjectMapper.Map(input, entity);
            await _entityRepository.UpdateAsync(entity);
        }

        public async Task Delete(EntityDto<long> input)
        {
            //TODO:删除前的逻辑判断，是否允许删除
            await _entityRepository.DeleteAsync(input.Id);
        }

        public async Task BatchDelete(List<long> input)
        {
            // TODO:批量删除前的逻辑判断，是否允许删除
            await _entityRepository.DeleteAsync(s => input.Contains(s.Id));
        }

        public async Task BatchDeleteByPatientId(int input)
        {
            // TODO:批量删除前的逻辑判断，是否允许删除
            await _entityRepository.DeleteAsync(s => s.PatientId == input);
        }

        public async Task BatchDeleteByRecordId(int input)
        {
            // TODO:批量删除前的逻辑判断，是否允许删除
            await _entityRepository.DeleteAsync(s => s.RecordId == input);
        }

    }
}
